package com.example.base.base.viewmodel

import androidx.lifecycle.viewModelScope
import com.example.base.base.mvi.IUiEffect
import com.example.base.base.mvi.IUiIntent
import com.example.base.base.mvi.IUiState
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch

/**
 * @Description
 * @department 城市元宇宙组
 * @Author niushilong
 * @Date 2024-04-06 17:59
 */
abstract class BaseVBViewModel<UiIntent: IUiIntent, UiState: IUiState, UiEffect: IUiEffect>: BaseViewModel() {

    // 保存页面持久性UI状态
    private val _uiStateFlow: MutableStateFlow<UiState> = MutableStateFlow(initUiState())
    val uiStateFlow: MutableStateFlow<UiState> = _uiStateFlow

    // 保存页面一次性UI状态
    private val _effectFlow: MutableSharedFlow<UiEffect> = MutableSharedFlow()
    val effectFlow: SharedFlow<UiEffect> by lazy { _effectFlow.asSharedFlow() }

    // 接收页面事件
    private val _uiIntentFlow = Channel<UiIntent>(Channel.UNLIMITED)

    // 发送一次性数据
    protected fun sendEffect(builder: suspend () -> UiEffect?) = viewModelScope.launch {
        builder()?.let { _effectFlow.emit(it) }
    }

    // 发送一次性数据
    protected suspend fun sendEffect(uiEffect: UiEffect){
        _effectFlow.emit(uiEffect)
    }

    // 更新页面状态
    fun updateUiState(recode: UiState.() -> UiState){
        _uiStateFlow.update {
            recode(it)
        }
    }

    // 发送事件
    fun sendUiIntent(uiIntent: UiIntent){
        viewModelScope.launch{
            _uiIntentFlow.send(uiIntent)
        }
    }

    init {
        // 观察者模式当事件到来时自动处理
        viewModelScope.launch {
            _uiIntentFlow.consumeAsFlow().collect{ intent -> // 事件
                // 处理事件
                handleIntent(intent)
            }
        }
    }

    // 每个页面的页面状态不同，由各个页面自主实现
    abstract fun initUiState(): UiState

    // 每个页面处理事件逻辑不同，自主实现
    abstract fun handleIntent(intent: UiIntent)
}